package com.atguigu.spzx.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.cart.service.CartService;
import com.lyb.common.utils.AuthContextUtil;
import com.lyb.spzx.feign.product.ProductFeignClient;
import com.lyb.spzx.model.dto.system.system.user.UserInfo;
import com.lyb.spzx.model.entity.h5.CartInfo;
import com.lyb.spzx.model.entity.product.ProductSku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    ProductFeignClient productFeignClient;

    private String getCartKey(Long userId) {
        //定义key user:cart:userId
        return "user:cart:" + userId;
    }
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前登录用户的id
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);
        //获取缓存对象
        Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));
        CartInfo cartInfo = null;
        //判断购物车是否有该商品，如果有，数量增加
        if (cartInfoObj != null){
            cartInfo = JSON.parseObject(cartInfoObj.toString(), CartInfo.class);
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setUpdateTime(new Date());
            cartInfo.setIsChecked(1); //默认勾选该商品 1-勾选
        }else {
            //购物车没有该商品，添加
            cartInfo = new CartInfo();
            //购物车数据是从商品详情得到{skuInfo}
            ProductSku productSku = productFeignClient.getBySkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());

        }

        //将商品缓存到Redis中
        redisTemplate.opsForHash()
                .put(cartKey,String.valueOf(skuId), JSON.toJSONString(cartInfo));

    }

    @Override
    public List<CartInfo> cartList() {
        //获取当前登录的用户信息
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        //获取数据
        List<Object> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(cartInfoList)){
            List<CartInfo> cartInfos = cartInfoList.stream().map(cartInfoJson ->
                    JSON.parseObject(cartInfoJson.toString(), CartInfo.class)).collect(Collectors.toList());
            return cartInfos;
        }

        return new ArrayList<>();
    }

    @Override
    public void deleteCart(Long skuId) {
        //获取用户信息
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        redisTemplate.opsForHash().delete(cartKey, String.valueOf(skuId));
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //获取当前用户信息
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);
        //判断key是否存在
        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));
        if (hasKey){
            //key存在，获取对应的value
            String cartInfoJson = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId)).toString();
            //转成对象
            CartInfo cartInfo = JSON.parseObject(cartInfoJson, CartInfo.class);
            //修改isChecked
            cartInfo.setIsChecked(isChecked);
            //保存到Redis
            redisTemplate.opsForHash().put(cartKey,String.valueOf(skuId), JSON.toJSONString(cartInfo));
        }
    }

    @Override
    public void allCheckCard(Integer isChecked) {
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        //获取所有购物车数据
        List<Object> values = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(values)){
            Stream<CartInfo> cartInfoStream = values.stream().map(cartInfoJson -> {
                CartInfo cartInfo = JSON.parseObject(cartInfoJson.toString(), CartInfo.class);
                cartInfo.setIsChecked(isChecked);
                return cartInfo;
            });
            //遍历数据，保存Redis
            cartInfoStream.forEach(cartInfo ->
                    redisTemplate.opsForHash().put(cartKey,String.valueOf(cartInfo.getSkuId()),JSON.toJSONString(cartInfo)));
        }
    }

    @Override
    public void clearCart() {
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getAllCkecked() {
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        //获取所有购物车选项
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(objectList)){
            List<CartInfo> cartInfos = objectList.stream().map(cartInfoJson ->
                    JSON.parseObject(cartInfoJson.toString(), CartInfo.class)).collect(Collectors.toList());
            List<CartInfo> cartInfoList = cartInfos.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
            return cartInfoList;
        }
        return new ArrayList<>();
    }

    @Override
    public void deleteChecked() {
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(objectList)){
            List<CartInfo> cartInfoList = objectList.stream().map(cartInfoJson -> JSON.parseObject(cartInfoJson.toString(), CartInfo.class)).collect(Collectors.toList());
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked() == 1){
                    redisTemplate.opsForHash().delete(cartKey,String.valueOf(cartInfo.getSkuId()));
                }
            }
        }
    }
}
